package com.whl.user.service.impl;

import com.whl.basic.constant.VerifyCodeConstants;
import com.whl.basic.exception.BusinessException;
import com.whl.basic.util.MD5Utils;
import com.whl.basic.util.StrUtils;
import com.whl.user.domain.Logininfo;
import com.whl.user.domain.User;
import com.whl.user.dto.EmailDto;
import com.whl.user.dto.UserDto;
import com.whl.user.mapper.LogininfoMapper;
import com.whl.user.mapper.UserMapper;
import com.whl.user.service.IUserService;
import com.whl.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 业务实现类：
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 手机号注册
     * @param userDto
     */
    @Override
    public void phoneRegister(UserDto userDto) {
        // 获取手机号
        String phone = userDto.getPhone();
        // 获取输入的手机验证码
        String phoneCode = userDto.getPhoneCode();
        // 获取密码
        String password = userDto.getPassword();
        // 获取第二次的密码
        String passwordRepeat = userDto.getPasswordRepeat();
        // 1.校验 - 空值校验
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(phoneCode)
        || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordRepeat)){
            throw new BusinessException("数据不能为空!!!");
        }
        // 2.校验 - 密码是否正确
        if(!password.equals(passwordRepeat)){
            throw new BusinessException("密码错误，请重新输入!!!");
        }
        // 3.校验 - 验证码是否过期
        Object redisCode = redisTemplate.opsForValue().get(VerifyCodeConstants.REGISTERCODE_PREFIX + phone);
        if(redisCode == null){ // 验证码过期了
            throw new BusinessException("验证码失效了，请重新获取!!!");
        }
        // 4.校验 - 验证码是否正确  9527:1223555555
        String codeTemp = redisCode.toString().split(":")[0];
        if(!codeTemp.equalsIgnoreCase(phoneCode)){
            throw new BusinessException("验证码错误，请重新输入!!!");
        }
        // 5.保存数据
        // 先保存到logininfo
        // 一个对象保存到另一个对象中可以用 - xxx2yyy
        User user = userDto2User(userDto);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.save(logininfo); // 添加之后可以获取自增长id

        // 再保存到user
        user.setLogininfoId(logininfo.getId());
        userMapper.save(user);
        
    }

    /**
     * 邮箱注册
     * @param emailDto
     */
    @Override
    public void emailRegister(EmailDto emailDto) {
        // 获取邮箱
        String email = emailDto.getEmail();
        // 获取密码
        String password = emailDto.getPassword();
        // 获取第二次输入的密码
        String passwordRepeat = emailDto.getPasswordRepeat();
        // 校验 - 空值校验
        if(StringUtils.isEmpty(email) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordRepeat)){
            throw new BusinessException("数据不能为空!!!");
        }
        // 校验 - 密码是否一致
        if(!password.equals(passwordRepeat)){
            throw new BusinessException("两次密码不一致!!!");
        }
        // 保存数据
        // 先保存到logininfo
        User user = emailDto2User(emailDto);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.save(logininfo); // 会返回一个自增长的id

        // 再保存到user
        user.setLogininfoId(logininfo.getId());
        userMapper.save(user);
    }

    private User emailDto2User(EmailDto emailDto) {
        User user = new User();
        user.setUsername(emailDto.getEmail());
        user.setEmail(emailDto.getEmail());
        // 获取盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 获取加密加盐后的密码
        String md5Password = MD5Utils.encrypByMd5(emailDto.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5Password);
        return user;
    }

    private User userDto2User(UserDto userDto) {
        User user = new User();
        user.setUsername(userDto.getPhone());
        user.setPhone(userDto.getPhone());
        // 获取盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 获取加密加盐之后的密码
        String md5Password = MD5Utils.encrypByMd5(userDto.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5Password);
        return user;
    }

    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        // 按照同名属性赋值
        BeanUtils.copyProperties(user,logininfo);
        // 当前对象是用户
        logininfo.setType(1);
        return logininfo;
    }


    @Override
    public void add(User user) {
        // 1.处理盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 2.调用md5工具类，给密码加密加盐
        String md5Password = MD5Utils.encrypByMd5(user.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5Password);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.save(logininfo);
        super.add(user);
    }

    @Override
    public void delete(Long id) {
        // 根据id查询到user
        User user = userMapper.findOne(id);
        // 删除登录信息表数据
        logininfoMapper.delete(user.getLogininfoId());
        // 删除user表数据
        super.delete(id);
    }

    @Override
    public void update(User user) {
        // 1.处理盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 2.调用md5工具类，给密码加密加盐
        String md5Password = MD5Utils.encrypByMd5(user.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5Password);
        // 用户user：createtime和logininfo_id不能修改
        // 3.获取登录信息
        Long logininfoId = userMapper.findOne(user.getId()).getLogininfoId();
        // 登录信息logininfo：type不修改
        Logininfo logininfo = user2Logininfo(user);
        logininfo.setId(logininfoId);
        logininfoMapper.update(logininfo);
        super.update(user);
    }
}
